package com.salesmanager.core.business.customer.model;

import com.salesmanager.core.business.common.model.audit.AuditListener;
import com.salesmanager.core.business.common.model.audit.AuditSection;
import com.salesmanager.core.business.common.model.audit.Auditable;
import com.salesmanager.core.business.generic.model.SalesManagerEntity;
import com.salesmanager.core.business.user.model.Group;
import com.salesmanager.core.constants.SchemaConstant;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Index;
import org.hibernate.validator.constraints.Email;

import javax.persistence.*;
import java.util.*;

@Entity
@EntityListeners(value = AuditListener.class)
@Table(name = "CUSTOMER",uniqueConstraints = {
        @UniqueConstraint(columnNames = {"TELPHONE"},name = "IDX_TELPHONE")
})
public class Customer extends SalesManagerEntity<Long, Customer> implements Auditable{
	private static final long serialVersionUID = -6966934116557219193L;
	
	@Id
	@Column(name = "CUSTOMER_ID", unique=true, nullable=false)
	@TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT",
	    pkColumnValue = "CUSTOMER_SEQ_NEXT_VAL",initialValue = 100000, allocationSize = 50)
	@GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
	private Long id;

    @Embedded
    private AuditSection auditSection = new AuditSection();
	
	/*@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, mappedBy = "customer")
	private Set<CustomerAttribute> attributes = new HashSet<CustomerAttribute>();*/

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "customer")
    private Set<CustomerAuths> auths = new HashSet<CustomerAuths>();
	
	@Column(name="CUSTOMER_GENDER", length=1, nullable=true)
	@Enumerated(value = EnumType.STRING)
	private CustomerGender gender; //性别

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="CUSTOMER_DOB")
	private Date dateOfBirth; //出生日期
	
	@Email
	@Column(name="CUSTOMER_EMAIL_ADDRESS", length=64)
	private String emailAddress;
	
	@Column(name="CUSTOMER_NICK", length=64)
	private String nick;    //昵称

	@Column(name="CUSTOMER_COMPANY", length=100)
	private String company;
	
//	@Column(name="CUSTOMER_PASSWORD", length=50)
//	private String password;   //密码


	@Column(name="CUSTOMER_ANONYMOUS")
	private boolean anonymous; //匿名

    @Column(name = "DEPTH")
    private Integer depth;

    @Column(name = "LINEAGE")
    private String lineage;

    @Column(name="TELPHONE",length = 20)
    private String telphone;

    @Column(name="ADDRESS")
    private String address;

    @Column(name="DIFF_DEVICE")
    private String diffDevice;


    @Column(name="DEVICE_TOKEN")
    private String deviceToken; //设备唯一标识

    @Column(name = "REAL_NAME",columnDefinition = "varchar(64) COMMENT '真是姓名'")
    private String realName;//真是姓名

    @Column(name = "ID_CARD",columnDefinition = "varchar(18) COMMENT '身份证号'")
    private String idCard; //身份证号

    @Column(name = "ALIPAY",columnDefinition = "varchar(64) COMMENT '真是姓名'")
    private String alipay;//支付宝

    @Column(name = "BANK_CARD",columnDefinition = "varchar(32) COMMENT '银行卡号'")
    private String bankCard;//银行卡号

    @Column(name = "APP_KEY",columnDefinition = "varchar(64) COMMENT '友盟APP_KEY'")
    private String appKey;

    @Column(name="OPENID")
    private String openId;

    @Column(name="CHANNEL")
    private String channel;

    public String getDeviceToken() {
        return deviceToken;
    }

    public void setDeviceToken(String deviceToken) {
        this.deviceToken = deviceToken;
    }

    @ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.REFRESH})
	@JoinTable(name = "CUSTOMER_GROUP", joinColumns = {
			@JoinColumn(name = "CUSTOMER_ID", nullable = false, updatable = false) }
			, 
			inverseJoinColumns = { @JoinColumn(name = "GROUP_ID", 
					nullable = false, updatable = false) }
	)
	@Cascade({
		org.hibernate.annotations.CascadeType.DETACH,
		org.hibernate.annotations.CascadeType.LOCK,
		org.hibernate.annotations.CascadeType.REFRESH,
		org.hibernate.annotations.CascadeType.REPLICATE
		
	})
	private List<Group> groups = new ArrayList<Group>();

    @OneToOne(optional = false,targetEntity = CustomerAccount.class, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
	private CustomerAccount customerAccount;

    public Customer() {
	}

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public Integer getDepth() {
        return depth;
    }

    public void setDepth(Integer depth) {
        this.depth = depth;
    }

    public String getLineage() {
        return lineage;
    }

    public void setLineage(String lineage) {
        this.lineage = lineage;
    }

    public String getOpenId() {
        return openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    public Customer(Long id) {
		this.id = id;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

    public CustomerGender getGender() {
        return gender;
    }

    public void setGender(CustomerGender gender) {
        this.gender = gender;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    public String getNick() {
        return nick;
    }

    public void setNick(String nick) {
        this.nick = nick;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public boolean isAnonymous() {
        return anonymous;
    }

    public void setAnonymous(boolean anonymous) {
        this.anonymous = anonymous;
    }

    public List<Group> getGroups() {
        return groups;
    }

    public void setGroups(List<Group> groups) {
        this.groups = groups;
    }

    public CustomerAccount getCustomerAccount() {
        return customerAccount;
    }

    public void setCustomerAccount(CustomerAccount customerAccount) {
        this.customerAccount = customerAccount;
    }

    public String getTelphone() {
        return telphone;
    }

    public void setTelphone(String telphone) {
        this.telphone = telphone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public AuditSection getAuditSection() {
        return auditSection;
    }

    @Override
    public void setAuditSection(AuditSection audit) {
        this.auditSection = audit;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public String getAlipay() {
        return alipay;
    }

    public void setAlipay(String alipay) {
        this.alipay = alipay;
    }

    public String getBankCard() {
        return bankCard;
    }

    public void setBankCard(String bankCard) {
        this.bankCard = bankCard;
    }

    public String getAppKey() {
        return appKey;
    }

    public void setAppKey(String appKey) {
        this.appKey = appKey;
    }

    public Set<CustomerAuths> getAuths() {
        return auths;
    }

    public void setAuths(Set<CustomerAuths> auths) {
        this.auths = auths;
    }

    public String getDiffDevice() {
        return diffDevice;
    }

    public void setDiffDevice(String diffDevice) {
        this.diffDevice = diffDevice;
    }
}
